package com.py.framework.core.utils;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

/**
 * @Description: 自定义线程池, 提供阻塞线程池以及固定大小线程池等
 * @author Leegern   
 * @date 2014年5月23日 上午9:32:04 
 * @version v1.0
 */
public class ThreadExecutor {
	/**
	 * log4j实例
	 */
	private static final Logger logger = Logger.getLogger(ThreadExecutor.class);
	
	/**
	 * 默认线程池大小是处理器个数
	 */
	private static final int DEFAULT_POOL_SIZE = Runtime.getRuntime().availableProcessors();
	
	
	/**
	 * 创建固定大小的阻塞式的线程池
	 * @param poolSize 线程个数
	 * @return
	 */
	public static ExecutorService newBlockingThreadPool(int poolSize) {
		return newBlockingThreadPool(poolSize, poolSize);
	} 
	
	/**
	 * 创建固定大小的阻塞式的线程池, 并且指定工作队列大小
	 * @param poolSize 线程个数
	 * @param queueSize 队列大小
	 * @return
	 */
	public static ExecutorService newBlockingThreadPool(int poolSize, int queueSize) {
		if (poolSize < 2) {
			poolSize = DEFAULT_POOL_SIZE;
		}
		if (queueSize < poolSize) {
			queueSize = poolSize;
		}
		ExecutorService es = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(queueSize), new RejectedExecutionHandler() {
			/**
			 * 自定义拒绝策略, 当工作队列满时, 生产者调用put阻塞
			 */
			@Override
			public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
				if (! executor.isShutdown()) {
					try {
						executor.getQueue().put(r);
					} catch (InterruptedException e) {
						 Thread.currentThread().interrupt();
						logger.error("Create blocking thread pool error !", e);
					}
				}
			}
		});
		return es;
	} 
	
	/**
	 * 创建固定大小的非阻塞式的线程池
	 * @param poolSize 线程个数
	 * @return
	 */
	public static ExecutorService newFixedThreadPool(int poolSize) {
		if (poolSize < 2) {
			poolSize = DEFAULT_POOL_SIZE;
		}
		return Executors.newFixedThreadPool(poolSize);
	}
	
	/**
	 * 创建无界线程池
	 * @return
	 */
	public static ExecutorService newCachedThreadPool() {
		return Executors.newCachedThreadPool();
	}
	
	/**
	 * 创建单个后台线程
	 * @return
	 */
	public static ExecutorService newSingleThread() {
		return Executors.newSingleThreadExecutor();
	}
	
	/**
	 * 创建固定大小的调度任务线程池
	 * @param poolSize 线程个数
	 * @return
	 */
	public static ScheduledExecutorService newScheduledThreadPool(int poolSize) {
		return Executors.newScheduledThreadPool(poolSize);
	}
	
	/**
	 * 关闭线程池
	 * @param es
	 */
	public static void close(ExecutorService es) {
		if (null != es) {
			es.shutdown();
		}
	}
}